package main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"gitee.com/rw555/fdsmastergo/internal/monitor"
	"gitee.com/rw555/fdsmastergo/internal/web_api"
	"gitee.com/rw555/fdsmastergo/pkg/device"
	"gitee.com/rw555/fdsmastergo/pkg/device/mock"
	"gitee.com/rw555/fdsmastergo/pkg/keypad"
	"gitee.com/rw555/fdsmastergo/pkg/logger"
	"gitee.com/rw555/fdsmastergo/pkg/version"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

// 自定义日志中间件
func CustomLogger() gin.HandlerFunc {
	return func(c *gin.Context) {
		startTime := time.Now()

		c.Next()

		endTime := time.Now()
		latency := endTime.Sub(startTime)

		logger.NetworkInfo("HTTP Request",
			zap.String("method", c.Request.Method),
			zap.String("path", c.Request.URL.Path),
			zap.String("ip", c.ClientIP()),
			zap.Int("status", c.Writer.Status()),
			zap.Duration("latency", latency),
		)
	}
}

func setupGinServer(m *monitor.Monitor, dev device.Device) (*gin.Engine, *http.Server, error) {
	// 设置 Gin 为发布模式
	gin.SetMode(gin.ReleaseMode)

	// 使用 gin.New() 替代 gin.Default()
	r := gin.New()

	// 添加 Recovery 中间件
	r.Use(gin.Recovery())

	// 添加自定义日志中间件
	r.Use(CustomLogger())

	// 设置可信代理
	trustedProxies := []string{"127.0.0.1"}
	if err := r.SetTrustedProxies(trustedProxies); err != nil {
		return nil, nil, fmt.Errorf("设置可信代理失败: %w", err)
	}

	handler := web_api.NewHandler(m, dev)
	r.GET("/current", handler.GetCurrentTemp)
	r.GET("/history", handler.GetHistory)
	r.POST("/internal/refresh-config", func(c *gin.Context) {
		if err := m.RefreshConfig(c); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		c.JSON(http.StatusOK, gin.H{"message": "配置已刷新"})
	})
	r.GET("/api/status", func(c *gin.Context) {
		temperature, power, modes, heatingStatus, pumpStatus, currentWorkingMinutes := m.GetStatus()
		c.JSON(http.StatusOK, gin.H{
			"temperature":             temperature,
			"power":                   power,
			"modes":                   modes,
			"heating_status":          heatingStatus,
			"cooling_status":          pumpStatus,
			"current_working_minutes": currentWorkingMinutes,
		})
	})
	r.POST("/api/mode", func(c *gin.Context) {
		var req struct {
			Mode   string `json:"mode"`
			Option string `json:"option"`
		}
		if err := c.BindJSON(&req); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求数据"})
			return
		}
		logger.OperationInfo("设置模式", zap.String("mode", req.Mode), zap.String("option", req.Option))
		if err := m.SetMode(req.Mode, req.Option); err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		c.JSON(http.StatusOK, gin.H{"message": "设置成功"})
	})

	port := "0.0.0.0:8081" // 监听所有网络接口
	logger.SystemInfo("Web服务器启动", zap.String("port", port))

	// 创建HTTP服务器
	srv := &http.Server{
		Addr:    port,
		Handler: r,
	}

	return r, srv, nil
}

func testSimulateKeypad(dev device.Device) {
	// 创建退出通道
	quit := make(chan struct{})
	defer close(quit)

	// 启动随机按键模拟
	dev.(*mock.MockDevice).SimulateRandomKeyPress(quit)
}

func main() {
	logger.Configure(logger.Config{
		EnableConsole:       true,
		EnableCaller:        true,
		LogDirByServiceName: "monitor_server",
		MaxSize:             1,
		MaxBackups:          3,
		MaxAge:              3,
		SystemLogLevel:      zapcore.InfoLevel,
		OperationLogLevel:   zapcore.InfoLevel,
		NetworkLogLevel:     zapcore.InfoLevel,
		OtherLogLevel:       zapcore.DebugLevel,
	})
	defer logger.Sync()

	// 输出版本信息
	vInfo := version.NewInfo("monitor_server")
	logger.SystemInfo("监控服务启动",
		zap.String("version", vInfo.Version),
		zap.String("gitCommit", vInfo.GitCommit),
		zap.String("buildTime", vInfo.BuildTime),
		zap.String("platform", vInfo.Platform))

	// 初始化模拟设备
	dev := mock.NewMockDevice()
	//testSimulateKeypad(dev)

	// 初始化按键扫描器
	keyScanner := keypad.NewScanner(dev.AsKeypad(), nil)

	// 初始化监控任务
	m, err := monitor.NewMonitor(dev, keyScanner)
	if err != nil {
		logger.SystemError("初始化监控失败", zap.Error(err))
		return
	}
	m.Start()

	// 创建一个通道用于接收终止信号
	quit := make(chan os.Signal, 1)
	// 监听 SIGINT (Ctrl+C) 和 SIGTERM 信号
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

	// 启动 Gin 服务器
	_, srv, err := setupGinServer(m, dev)
	if err != nil {
		logger.SystemError("设置 Gin 服务器失败", zap.Error(err))
		return
	}

	// 在单独的goroutine中启动服务器
	go func() {
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			logger.SystemError("启动服务器失败", zap.Error(err))
		}
	}()

	// 等待中断信号
	<-quit
	logger.SystemInfo("正在关闭服务器...")

	// 创建一个5秒超时的上下文
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	// 优雅地关闭服务器
	if err := srv.Shutdown(ctx); err != nil {
		logger.SystemError("服务器关闭异常", zap.Error(err))
	}

	// 停止监控任务
	m.Stop()

	logger.SystemInfo("服务器已安全关闭")
}
